home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
libs
/
knowhow4
/
mouse.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1994-10-10
|
7KB
|
374 lines
/*
ATTENTION! If compiling in tiny, small or medium memory model,
use Options | Compiler | Code Generation | Assume SS Equals DS never
settings !
*/
#include <graphics.h>
#include "graphpp.h"
// #include "graph.h"
#ifndef __GEOM
#include "geom.h"
#endif
#include "mouse.h"
// Virtual window management
static mousemanager MouseManager;
mousemanager * mousehandler::manager=& MouseManager;
int mousemanager::Nbuttons=0;
//
// *************************************************
//
static int driverInstalled=0;
static int mouseInit() // returns # of buttons , not user-available
// user should call mouseReset
{ driverInstalled=1;
asm{
xor ax,ax
mov es,ax
mov bx,(33h*4)
mov ax,es:[bx]
or ax,es:[bx+2]
jz no_driver
mov ax,0
int 33h
or ax,ax
jz no_driver
}
return _BX;
no_driver:
driverInstalled=0;
return 0;
}
int mouseType() // 0 - no mouse , 2,3
{return mousemanager::Nbuttons;}
void mouseReset()
{
if(!driverInstalled) return;
asm{
mov ax,0
int 33h
}
MouseManager. reset();
}
mousestatus mouseGetStatus()
{ mousestatus s;
if (driverInstalled)
{
asm {
mov ax,3
int 33h
}
s.buttonstate=_BX;
s.x=_CX;
s.y=_DX;
}
else
{
s.buttonstate=0;
s.x=0;
s.y=0;
}
return s;
}
void mouseSetPosition(loc at)
{
if(!driverInstalled) return;
_CX=at.X;
_DX=at.Y;
asm{
mov ax,4
int 33h
}
}
void mouseSetHorizontalRange(int xmin,int xmax)
{
if(!driverInstalled) return;
asm{
mov ax,7
mov cx,xmin
mov dx,xmax
int 33h
}
}
void mouseSetVerticalRange(int ymin,int ymax)
{
if(!driverInstalled) return;
asm{
mov ax,8
mov cx,ymin
mov dx,ymax
int 33h
}
}
void mouseSetRange(const rect& range)
{
mouseSetHorizontalRange(range.left(),range.right());
mouseSetVerticalRange(range.top(),range.bottom());
}
void mouseDefaultRange() // Graphic-mode only !
{
mouseSetRange(rect(loc(),screensize()));
}
void mouseSetSpeed(const loc& speed) // mickeys / 8 pixels
{
if(!driverInstalled) return;
_CX=speed.X;
_DX=speed.Y;
asm{
mov ax,15
int 33h
}
}
void mouseDefaultSpeed()
{
mouseSetSpeed(loc(8,16));
}
void mouseSetDoublingSpeed(int speed) // mickeys /second
{
if(!driverInstalled) return;
asm{
mov ax,19
mov dx,speed
int 33h
}
}
void mouseDefaultDoublingSpeed()
{
mouseSetDoublingSpeed(64);
}
void mouseDoublingOff()
{
mouseSetDoublingSpeed(34000);
}
unsigned mouseStateStorageSize()
{
if(!driverInstalled) return 2;
_AX=21;
asm int 33h;
return _BX;
}
void mouseSaveState(char far * buffer)
{
if(!driverInstalled) return ;
asm{
mov ax,22
les dx, buffer
int 33h
}
}
void mouseRestoreState(char far * buffer)
{
if(!driverInstalled) return ;
asm{
mov ax,23
les dx, buffer
int 33h
}
}
void mouseSetHandler (mousehandlerfunc handler)
{
if(!driverInstalled) return ;
_CX=mouseeventlow::MSALL;
asm{
mov ax,12
les dx,handler
int 33h
}
}
void mouseDisableHandler ()
{
if(!driverInstalled) return ;
_CX=mouseeventlow::MSNONE;
asm{
mov ax,12
xor dx,dx
mov es,dx
int 33h
}
}
void mouseShowCursor()
{
if(!driverInstalled) return ;
asm{
mov ax,1
int 33h
}
}
void mouseHideCursor()
{
if(!driverInstalled) return ;
asm{
mov ax,2
int 33h
}
}
void mouseSuspend()
{
mouseHideCursor();
mouseDisableHandler();
}
void mouseResume()
{
mouseShowCursor();
MouseManager.reset();
}
//
// *************************************************
//
mousehandler::mousehandler(unsigned callmask,rect * area):
EventMask(callmask),domain(0)
{
if (area) domain= new rect(*area);
manager->attach(this);
}
mousehandler::~mousehandler()
{
manager->detach(this);
if( domain) delete domain;
}
void huge _saveregs mousemanager::mainmousehandler()
{
mouseeventlow e;
e.evtype=_AX;e.buttonstatus=_BX;e.x=_CX;e.y=_DX;e.mx=_SI;e.my=_DI;
mousehandler * list=mousehandler::manager -> handlist;
mousehandler * ip;
loc point(e.x,e.y);
if(mousehandler::manager ->locked) return;
// Just ignore mouse event.
// more accurate action would be put this event in pending state,
// and then unlock() procedure should call handler again
// (in this case handler should consist of 2 parts:
// interrupt & strategy)
for(ip=list;ip && e.evtype ;ip=ip->next)
if ((ip->EventMask & e.evtype) && ip->covers (point) )
ip->handle(e);
}
mousemanager::mousemanager() :handlist(0),locked(0)
{
Nbuttons=mouseInit();
mouseSetHandler(mousemanager::mainmousehandler);
}
void mousemanager::reset()
{
mouseSetHandler(mousemanager::mainmousehandler);
}
void mousemanager::attach ( mousehandler * handler)
{
locked=1;
handler->next= handlist;
handlist=handler;
locked=0;
}
void mousemanager::detach (mousehandler * handler)
{ mousehandler * ip, * prev;
for (prev=0,ip=handlist;ip && (ip != handler);prev=ip,ip=ip->next)
; // just look through
if (ip==0) return; // Not found !
locked=1;
if (prev==0) handlist=handlist->next; // remove head
else prev->next=ip->next; // remove inside chain
locked=0;
}
mousemanager::~mousemanager()
{
mouseDisableHandler();
}
int mousehole::covers(loc& pos) const
{
return door.contains(pos);
}
void mousehole::handle(mouseeventlow& ev)
{
loc current(ev.x,ev.y);
if(isinside)
{
if (!covers(current)) {isinside=0;leave();}
}
else
{
if (covers(current)) {isinside=1;enter();}
}
}
mousehole::mousehole(rect hole):
mousehandler(mouseeventlow::MSMOVE),door(hole),isinside(0)
{ }